HTML5為了在不同情境下使用,設計了幾種溝通的方式,包含文件之間溝通的cross-document messaging、channel messaging,還有與伺服器溝通的server sent event以及web socket。今天先試試看最簡單的cross-document messaging。
先看一下所有溝通機制會使用的事件定義:
interface MessageEvent : Event {
readonly attribute any data;
readonly attribute DOMString origin;
readonly attribute DOMString lastEventId;
readonly attribute WindowProxy source;
readonly attribute MessagePortArray ports;
void initMessageEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in any dataArg,
in DOMString originArg,
in DOMString lastEventIdArg,
in WindowProxy sourceArg,
in MessagePortArray portsArg);
};
據說只有MessageEvent.data這個屬性是所有不同溝通方式會共用的,用來接收訊息。對於cross-document messaging,會用到的還有:
不過光這樣看不出要怎麼用,先寫個小程式來試試看:
<html lang="zh-TW">
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<style>
div {
border: solid 2px #336699;
margin: 10px;
padding: 5px;
border-radius: 5px;
vertical-align: top;
text-align: center;
display: inline-block;
}
.container {
background: #88BBFF;
width: 520px;
}
#msg {
background: #99CCFF;
border: dotted 1px #4477AA;
width: 480px;
margin: 0px;
text-align: left;
font-size: 12px;
}
</style>
<script>
function init() {
var form = document.getElementById('form1');
var input = document.getElementById('input');
var target = document.getElementById('target');
form.onsubmit = function(){
try {
target.contentWindow.postMessage(input.value, 'http://www.fillano.idv.tw');
} catch(e) {
alert(e);
} finally {
input.value = '';
input.focus();
return false;
}
};
window.addEventListener('message', function(e) {
var str = '<li>';
str += '[' + e.origin + ']';
str += '[' + e.source + ']';
str += '[' + e.ports + ']';
str += ' : ';
str += e.data;
str += '</li>\n';
document.getElementById('msg').innerHTML += str;
}, false);
}
</script>
<div><div class="container"><form id="form1"><input type="text" size="30" id="input"></form></div><br>
<div class="container">Returned Messages.<div id="msg"></div></div></div>
<iframe src="http://www.fillano.idv.tw/test631a.html" id="target" width="520" height="600" scrolling="no" frameborder="1"></iframe>
<script>
init();
</script>
然後iframe裡面的test631a.html:
<html lang="zh-TW">
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<style>
div {
border: solid 2px #336699;
margin: 10px;
padding: 5px;
border-radius: 5px;
vertical-align: top;
text-align: center;
display: inline-block;
}
#container {
background: #88BBFF;
width: 480px;
}
#panel {
background: #99CCFF;
border: dotted 1px #4477AA;
width: 90%;
margin: 0px;
text-align: left;
font-size: 12px;
}
</style>
<div id="container">Received messages.<div id="panel"></div></div>
<script>
window.addEventListener('message', function(e) {
var str = '<li>';
str += '[' + e.origin + ']';
str += '[' + e.source + ']';
str += '[' + e.ports + ']';
str += ' : ';
str += e.data;
str += '</li>\n';
document.getElementById('panel').innerHTML += str;
e.source.postMessage('got it at '+(new Date())+'.', e.origin);
}, false);
</script>
測試很簡單,從input輸入文字,就會顯示在iframe,然後回傳"got it"及時間。目前最新的瀏覽器都可以支援,包括Firefox4, Chrome7, IE9, Opera, Safari...
利用這樣的方式,就可以做到跟iframe裡面的網頁做雙向半雙工的訊息傳遞。(標準是這樣說,不過要測試他是不是半雙工可能會有點困難)另外,有一些點需要注意: